<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns='http://www.w3.org/1999/xhtml'
  xmlns:n='http://nevow.com/ns/nevow/0.1'>
  <!-- vi:ft=html
  -->
  <head>
    <meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />
    <n:invisible n:render="liveglue" />
    <title>TypeAhead Demo</title>
    <script type='text/javascript' language='javascript'>
// <![CDATA[
// add events in a cross-browser way
function xbAddEvent(obj, evType, fn, useCapture){
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
  } else {
    alert("Handler could not be attached");
  }
}

function selectRange(ele, start, end)
{
    var orig = ele;
    ele = $(ele);
    if (ele == null)
    {
        alert("selectRange() can't find an element with id: " + orig + ".");
        return;
    }

    if (ele.setSelectionRange)
    {
        ele.setSelectionRange(start, end);
    }
    else if (ele.createTextRange)
    {
        var range = ele.createTextRange();
        range.moveStart("character", start);
        range.moveEnd("character", end - ele.value.length);
        range.select();
    }

    ele.focus();
};

// 
function replaceDescription(result, node)
{
    var animal = result[0]; var descr = result[1];

    var widget = Nevow.Athena.Widget.get(node);
    var description = widget.nodeByAttribute('class', 'description');
    description.innerHTML = descr;

    // fill in the text field and select the portion that was guessed
    if (animal != null)
    {
        var typehere = node;
        var current = typehere.value;
        typehere.value = animal;
        selectRange(typehere, current.length, animal.length);
    }
}

//
function loadDescription(ev)
{
    // filter helpful keys like backspace
    if (ev.keyCode < 32) return;
    if (ev.keyCode >= 33 && ev.keyCode <= 46) return;
    if (ev.keyCode >= 112 && ev.keyCode <= 123) return;

    var typehere = ev.target;
    var typed = typehere.value;
    var d = Nevow.Athena.Widget.get(typehere).callRemote('loadDescription', typed);
    d.addCallback(replaceDescription, typehere);
}

Divmod.Base.addToCallStack(window, 'onload', function() {
    typeheres = MochiKit.DOM.getElementsByTagAndClassName('input', 'typehere');
    for (n=0; n<typeheres.length; n++) {
      xbAddEvent(typeheres[n], 'keyup', loadDescription, 1);
    }
});

// ]]>
    </script>
  </head>
  <body>
    <h2>Start typing an animal to see the description.</h2>
    <n:invisible n:render="typehereField" />
    <h2>You can also type in this one.  It does the same thing, independently
      of the other one.</h2>
    <n:invisible n:render="typehereField" />
  </body>
</html>

